#include <SFML\OpenGL.hpp>
#include <iostream>
#include <sstream>

namespace Private
{
	void glcShowErrorInner(const char* FileName, const char* FunctionName, const std::size_t Line, const GLenum ErrorCode);
}

///@brief Das Makro gibt einen Messagetext inklusiv auf der Konsole, fals ein OpenGL-Fehler aufgetreten ist.
///@details Die Meldung in der Konsole kann auch ignoriert werden. Der Dateiname und die Zeilennummer der Stelle wo "GLCSHOWERROR" aufgerufen wurde, wird ebenfalls angezeigt.
#define GLCSHOWERROR() \
do \
{ \
	const GLenum ErrorNumber = glGetError(); \
if (ErrorNumber != GL_NO_ERROR) \
	::Private::glcShowErrorInner(__FILE__, __FUNCTION__, __LINE__, ErrorNumber); \
} while (0)



//Source...
namespace Private
{
	bool AskAgainIfAnOpenglErrorOccurs = true;
	void glcShowErrorInner(const char* FileName, const char* FunctionName, const std::size_t Line, const GLenum ErrorCode)
	{
		if (ErrorCode == GL_NO_ERROR)
			return;
		std::stringstream ErrorText;
		ErrorText << "An OpenGL error occurred in function \"" << FunctionName << "\" at \"" << FileName << "\"(" << Line << ").\n";
		ErrorText << "Errorcode: " << ErrorCode << "\nErrormessage: ";
		switch (ErrorCode)
		{
		case GL_INVALID_ENUM:
			ErrorText << "Invalid enum\n";
			break;
		case GL_INVALID_VALUE:
			ErrorText << "Invalid value\n";
			break;
		case GL_INVALID_OPERATION:
			ErrorText << "Invalid operation\n";
			break;
		case GL_STACK_OVERFLOW:
			ErrorText << "Stack overflow\n";
			break;
		case GL_STACK_UNDERFLOW:
			ErrorText << "Stack underflow\n";
			break;
		case GL_OUT_OF_MEMORY:
			ErrorText << "Out of memory\n";
			break;
		default:
			ErrorText << "Unknown\n";
			break;
		}
		std::cout << ErrorText.str();
		if (AskAgainIfAnOpenglErrorOccurs)
		{
			std::cout << "\n"
				"If you want to continue the execution type \"Y\".\n"
				"If you don't want to be asked again type \"A\".\n"
				"When you type \"N\", the execution will be aborted." << std::endl;
			do
			{
#ifdef DEBUG
				__debugbreak();
#endif
				char InputChar;
				std::cin >> InputChar;
				InputChar = tolower(InputChar);
				switch (InputChar)
				{
				case 'y':
					return;
				case 'a':
					AskAgainIfAnOpenglErrorOccurs = false;
					return;
				case 'n':
					std::exit(65536 + ErrorCode);
				}
			} while (true);
		}
	}
}